package com.zlyx.easy.core.utils;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Arrays;

import com.zlyx.easy.core.app.AppUtils;
import com.zlyx.easy.core.loggers.Logger;

/**
 * 
 * @Auth 赵光
 * @Describle
 * @2019年1月3日 下午2:54:41
 */
public class ClassUtils {

	/**
	 * 获取当前类对象的的类名
	 * 
	 * @param o
	 * @return
	 */
	public static String name(Class<?> cls) {
		return cls == null ? null : cls.getName();
	}

	/**
	 * 获取当前类的精简类名
	 * 
	 * @param o
	 * @return
	 */
	public static String simpleName(Class<?> cls) {
		return cls == null ? null : cls.getSimpleName();
	}

	/**
	 * 调用构造方法实例化对象
	 * 
	 * @param tCls
	 * @return
	 */
	public static <T> T newInstance(Class<T> tCls) {
		try {
			return tCls.getConstructor().newInstance();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * 返回一个不为空的实例化对象
	 * 
	 * @param <T>
	 * @param o
	 * @param cls
	 * @return
	 */
	public static <T> T getInstance(T o, Class<T> cls) {
		if (o == null) {
			if (cls.isInterface()) {
				Logger.warn(cls, "接口{}没有指定实现类！", cls.getName());
				o = ClassUtils.getInstance(cls);
			} else {
				o = newInstance(cls);
			}
		}
		return o;
	}

	/**
	 * 给接口创建默认实现类
	 * 
	 * @param <T>
	 * @param tCls
	 * @return
	 */
	public static <T> T getInstance(Class<T> cls) {
		return getInstance(cls, new InvocationHandler() {
			@Override
			public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
				Logger.info(cls, "{}.{} args = {}", cls.getSimpleName(), method.getName(), Arrays.toString(args));
				return null;
			}
		});
	}

	/**
	 * 给接口创建默认实现类
	 * 
	 * @param <T>
	 * @param tCls
	 * @param handler
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public static <T> T getInstance(Class<T> cls, InvocationHandler handler) {
		if (!cls.isInterface()) {
			return (T) handler;
		}
		return (T) Proxy.newProxyInstance(cls.getClassLoader(), new Class[] { cls }, handler);
	}

	/**
	 * 判断是否继承关系
	 * 
	 * @param cls
	 * @param superClass
	 * @return
	 */
	public static boolean isAssignableFrom(Class<?> cls, Class<?> superClass) {
		if (cls == null || cls == Object.class) {
			return false;
		}
		if (cls == superClass || cls.isAssignableFrom(superClass)) {
			return true;
		}
		return isAssignableFrom(cls.getSuperclass(), superClass);
	}

	/**
	 * 获取项目路径
	 * 
	 * @param cls
	 * @return
	 */
	public static String getPath() {
		return System.getProperty("user.dir");
	}

	/**
	 * 获取参数类包名称
	 * 
	 * @param cls
	 * @return
	 */
	public static String getPackageName(Class<?> cls) {
		return cls.getPackage().getName();
	}

	/**
	 * 获取启动类路径
	 * 
	 * @param cls
	 * @return
	 */
	public static String getAppPath() {
		return getPackagePath(AppUtils.getMainClass());
	}

	/**
	 * 获取参数类包路径
	 * 
	 * @param cls
	 * @return
	 */
	public static String getPackagePath(Class<?> cls) {
		return getPath() + "\\src\\main\\java\\" + cls.getPackage().getName().replace(".", "\\");
	}

	/**
	 * 获取参数类路径
	 * 
	 * @param cls
	 * @return
	 */
	public static String getClassPath(Class<?> cls) {
		return getPackagePath(cls) + "\\" + cls.getSimpleName() + ".java";
	}
}
